package com.bjpowernode.dataservice.impl;

import com.bjpowernode.common.P2PConstants;
import com.bjpowernode.common.P2PKey;
import com.bjpowernode.mapper.BidInfoMapper;
import com.bjpowernode.mapper.FinanceAccountMapper;
import com.bjpowernode.mapper.LoanInfoMapper;
import com.bjpowernode.model.BidInfo;
import com.bjpowernode.model.FinanceAccount;
import com.bjpowernode.model.LoanInfo;
import com.bjpowernode.model.ext.BidLoanInfo;
import com.bjpowernode.service.BidInfoService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


@DubboService
public class BidInfoServiceImpl implements BidInfoService {

    @Resource
    private BidInfoMapper bidInfoMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private LoanInfoMapper loanInfoMapper;

    @Resource
    private FinanceAccountMapper financeAccountMapper;

    /**
     *
     * @return累计投资金额
     */
    @Override
    public BigDecimal querySumBidMoney() {

        ValueOperations valueOperations =redisTemplate.opsForValue();
        BigDecimal sumBidMoney = (BigDecimal) valueOperations.get(P2PKey.P2P_BID_MONEY_SUM);
        if (sumBidMoney==null){
            synchronized (this){
                sumBidMoney= (BigDecimal) valueOperations.get(P2PKey.P2P_BID_MONEY_SUM);
                if (sumBidMoney==null){
                    sumBidMoney=bidInfoMapper.selectBidMoney();
                    valueOperations.set(P2PKey.P2P_BID_MONEY_SUM,sumBidMoney,20, TimeUnit.MINUTES);
                }
            }
        }

        return bidInfoMapper.selectBidMoney();
    }

    /**
     * 查询某个产品最近的3条投资记录
     */
    @Override
    public List<BidLoanInfo> queryRecentlyBidRecordByLoanId(Integer loanId) {
        List<BidLoanInfo> bidLoanInfoList = bidInfoMapper.selectBidRecordByLoanId(loanId);
        return bidLoanInfoList;
    }

    @Override
    public List<BidLoanInfo> queryBidInfoByUid(Integer uid) {

        List<BidLoanInfo> bidLoanInfoList = bidInfoMapper.selectBidInfoByUid(uid);
        return bidLoanInfoList;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public boolean invest(Integer loanId, BigDecimal money,Integer uid) {

        boolean flag =false;
        int rows =0;

        //查询产品，信息
        LoanInfo loanInfo = loanInfoMapper.selectLoanInfoByPrimaryKey(loanId);;
        if (loanInfo!=null&&loanInfo.getProductStatus()==0){
            //做金额检查
            int bidMoney =money.intValue();
            int minMoney =loanInfo.getBidMinLimit().intValue();
            int maxMoney=loanInfo.getBidMaxLimit().intValue();
            int leftMoney=loanInfo.getLeftProductMoney().intValue();

            //判断金额
            if (bidMoney>maxMoney||bidMoney<minMoney||bidMoney>leftMoney){
                return flag;
            }

            //扣除金额，给账户上锁
            FinanceAccount financeAccount =financeAccountMapper.selectForUpdate(uid);
            if (financeAccount!=null){
                rows = financeAccountMapper.updateMoneyByInvest(uid,money);
                if (rows<1){
                    throw new RuntimeException("投资时，更新账户失败");
                }

                //扣除产品的剩余可投资金额
                rows = loanInfoMapper.updateLeftMoney(loanId,money);
                if (rows<1){
                    throw new RuntimeException("投资时，更新剩余可投资金额失败");
                }

                //添加一条投资记录
                BidInfo bidInfo =new BidInfo();
                bidInfo.setLoanId(loanId);
                bidInfo.setBidMoney(money);
                bidInfo.setBidTime(new Date());
                bidInfo.setBidStatus(1);
                bidInfo.setUid(uid);

                rows =bidInfoMapper.insertSelective(bidInfo);
                if (rows<1){
                    throw new RuntimeException("投资时，创建投资记录失败");
                }

                LoanInfo info =loanInfoMapper.selectByPrimaryKey(loanId);
                if (info.getLeftProductMoney().intValue()==P2PConstants.PRODUCT_TYPE_0){
                    //满标的，跟新产品的满标状态和时间
                    info.setProductStatus(P2PConstants.PRODUCT_TYPE_1);
                    info.setProductFullTime(new Date());
                    rows =loanInfoMapper.updateByPrimaryKeySelective(info);
                    if (rows<1){
                        throw new RuntimeException("投资时,更新产品状态失败");
                    }
                }
            }
        }

        return flag;
    }
}
